/*
 【入门】素数的个数
  题目描述
    编程求正整数 M 与 N 之间的所有素数的个数.（1 <= M <= N <= 10^6）
  输入格式
    输入只有一行，包括 2 个整数 M, N, 之间用一个空格分开。
  输出格式
    输出只有一行（这意味着末尾有一个回车符号），包括 1 个整数。
  输入数据 1
    1 20
  输出数据 1
    8
*/

#include <bits/stdc++.h>

using namespace std;

int a[1000010] = {};      // 数组 a 用来存放质数
int b[1000010] = {1, 1};  // b[i] 表示整数 i 表示是否是质数: 0 表示是质数或者未判断，1 表示非质数(合数)

int main() {
    int n;
    int m;
    int sum = 0;  // 用来统计从 1 到 n 之间的质数的个数
    int ans = 0;  // 用来统计从 m 到 n 之间的质数的个数

    cin >> m >> n;

    /*
      思路:
        1). 使用线性筛除法，将 1 ~ b 之间的非质数筛除掉!
        2). 然后再从筛除结果中找出 m 和 n 之间的质数
    */

    /* 线性筛除法核心代码 */
    for (int i = 2; i <= n; i++) {
        // 如果 i 是质数，则将其放到数组 a 中
        if (b[i] == 0) {  // 注意: 这里当 b[i] == 0，则 i 一定是质数！！！而不是未判断!
            a[sum++] = i;
            if (i >= m) {
                ans++;
            }
        }

        /*
          针对 i，遍历小于等于 i 的所有质数，针对每个质数进行如下处理(即循环体中的处理):
            1). 如果质数和 i 的乘积小于 n，则将该质数和 i 的乘积筛掉(标记该乘积为非质数)
                否则，循环退出；
            2). 当该质数是 i 的因数时，循环退出；
        */
        for (int j = 0; j < sum; j++){
            if (a[j] * i <= n) {
                b[a[j] * i] = 1;
            } else {
                break;
            }
            if (i % a[j] == 0) {
                break;
            }
        }
    }
    cout << ans;

    return 0;
}